import express from 'express';
import { body, validationResult } from 'express-validator';
import { User, UserLog } from '../models/index.js';
import { generateUserToken, authenticateUser } from '../middleware/auth.js';
import { smsGlobalLimiter, smsIpLimiter, loginLimiter, registerLimiter } from '../middleware/rateLimiter.js';
import { catchAsync, BusinessError } from '../middleware/errorHandler.js';
import { success } from '../utils/response.js';
import { sendSMS, verifyCode } from '../utils/sms.js';

const router = express.Router();

// 发送验证码
router.post('/send-code', 
  smsGlobalLimiter,
  smsIpLimiter,
  [
    body('phone')
      .isMobilePhone('zh-CN')
      .withMessage('请输入正确的手机号')
  ],
  catchAsync(async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      throw new BusinessError('参数验证失败', errors.array());
    }

    const { phone } = req.body;
    
    try {
      const result = await sendSMS(phone);
      
      res.json({
        code: 200,
        message: '验证码发送成功',
        data: {
          requestId: result.requestId,
          // 开发环境返回验证码
          ...(process.env.NODE_ENV === 'development' && { code: result.code })
        }
      });
    } catch (error) {
      throw new BusinessError(error.message || '验证码发送失败');
    }
  })
);

// 用户登录/注册
router.post('/login',
  loginLimiter,
  [
    body('phone')
      .isMobilePhone('zh-CN')
      .withMessage('请输入正确的手机号'),
    body('code')
      .isLength({ min: 6, max: 6 })
      .withMessage('验证码必须是6位数字')
  ],
  catchAsync(async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      throw new BusinessError('参数验证失败', errors.array());
    }

    const { phone, code } = req.body;
    const ip = req.ip;
    const userAgent = req.get('User-Agent');
    
    // 验证验证码
    try {
      verifyCode(phone, code);
    } catch (error) {
      throw new BusinessError(error.message);
    }
    
    // 查找或创建用户
    let user = await User.findByPhone(phone);
    let isNewUser = false;
    
    if (!user) {
      // 新用户注册
      user = await User.createUser({
        phone,
        register_channel: 'sms_login'
      });
      isNewUser = true;
      
      // 记录注册日志
      await UserLog.createRegisterLog(user, ip, userAgent);
    }
    
    if (!user.is_active) {
      throw new BusinessError('账户已被禁用，请联系客服');
    }
    
    // 更新登录信息
    await user.updateLoginInfo(ip);
    
    // 记录登录日志
    await UserLog.createLoginLog(user.id, ip, userAgent);
    
    // 生成JWT令牌
    const token = generateUserToken(user);
    
    res.json(success({
      user: user.toJSON(),
      token,
      isNewUser
    }, isNewUser ? '注册成功' : '登录成功'));
  })
);

// 获取用户信息
router.get('/me',
  catchAsync(async (req, res) => {
    const token = req.header('Authorization')?.replace('Bearer ', '');
    
    if (!token) {
      throw new BusinessError('请先登录', 401);
    }
    
    try {
      const jwt = await import('jsonwebtoken');
      const config = await import('../config/index.js');
      
      const decoded = jwt.default.verify(token, config.default.jwt.secret);
      const user = await User.findWithQuotas(decoded.userId);
      
      if (!user || !user.is_active) {
        throw new BusinessError('用户不存在或已被禁用', 401);
      }
      
      res.json(success({
        user: user.toJSON()
      }, '获取用户信息成功'));
    } catch (error) {
      if (error.name === 'JsonWebTokenError') {
        throw new BusinessError('无效的访问令牌', 401);
      }
      if (error.name === 'TokenExpiredError') {
        throw new BusinessError('访问令牌已过期', 401);
      }
      throw error;
    }
  })
);

// 刷新令牌
router.post('/refresh',
  catchAsync(async (req, res) => {
    const token = req.header('Authorization')?.replace('Bearer ', '');
    
    if (!token) {
      throw new BusinessError('请提供访问令牌', 401);
    }
    
    try {
      const jwt = await import('jsonwebtoken');
      const config = await import('../config/index.js');
      
      // 验证令牌（即使过期也要能解析）
      const decoded = jwt.default.verify(token, config.default.jwt.secret, { ignoreExpiration: true });
      const user = await User.findByPk(decoded.userId);
      
      if (!user || !user.is_active) {
        throw new BusinessError('用户不存在或已被禁用', 401);
      }
      
      // 生成新令牌
      const newToken = generateUserToken(user);
      
      res.json(success({
        token: newToken
      }, '令牌刷新成功'));
    } catch (error) {
      if (error.name === 'JsonWebTokenError') {
        throw new BusinessError('无效的访问令牌', 401);
      }
      throw error;
    }
  })
);

// 退出登录
router.post('/logout',
  catchAsync(async (req, res) => {
    // 客户端删除令牌即可，服务端暂不维护黑名单
    res.json(success(null, '退出登录成功'));
  })
);

// 更新用户信息
router.put('/profile',
  authenticateUser,
  [
    body('name')
      .optional()
      .isLength({ min: 1, max: 100 })
      .withMessage('姓名长度必须在1-100个字符之间'),
    body('nickname')
      .optional()
      .isLength({ min: 1, max: 100 })
      .withMessage('昵称长度必须在1-100个字符之间'),
    body('email')
      .optional()
      .isEmail()
      .withMessage('请输入正确的邮箱格式'),
    body('avatar')
      .optional()
      .isURL()
      .withMessage('头像必须是有效的URL')
  ],
  catchAsync(async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      throw new BusinessError('参数验证失败', errors.array());
    }

    const { name, nickname, email, avatar } = req.body;
    const user = req.user;

    // 检查邮箱是否已被其他用户使用
    if (email && email !== user.email) {
      const existingUser = await User.findOne({ where: { email } });
      if (existingUser && existingUser.id !== user.id) {
        throw new BusinessError('该邮箱已被其他用户使用');
      }
    }

    // 更新用户信息
    const updateData = {};
    if (name !== undefined) updateData.name = name;
    if (nickname !== undefined) updateData.nickname = nickname;
    if (email !== undefined) updateData.email = email;
    if (avatar !== undefined) updateData.avatar = avatar;

    await user.update(updateData);

    // 记录操作日志
    await UserLog.create({
      user_id: user.id,
      action: 'profile_update',
      details: JSON.stringify(updateData),
      ip: req.ip,
      user_agent: req.get('User-Agent')
    });

    res.json({
      code: 200,
      message: '用户信息更新成功',
      data: {
        user: user.toJSON()
      }
    });
  })
);

// 修改密码
router.put('/password',
  authenticateUser,
  [
    body('currentPassword')
      .notEmpty()
      .withMessage('请输入当前密码'),
    body('newPassword')
      .isLength({ min: 6, max: 50 })
      .withMessage('新密码长度必须在6-50个字符之间')
      .matches(/^(?=.*[a-zA-Z])(?=.*\d)/)
      .withMessage('新密码必须包含至少一个字母和一个数字'),
    body('confirmPassword')
      .custom((value, { req }) => {
        if (value !== req.body.newPassword) {
          throw new Error('确认密码与新密码不一致');
        }
        return true;
      })
  ],
  catchAsync(async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      throw new BusinessError('参数验证失败', errors.array());
    }

    const { currentPassword, newPassword } = req.body;
    const user = req.user;

    // 验证当前密码
    if (!user.password) {
      throw new BusinessError('账户未设置密码，请联系客服');
    }

    const isCurrentPasswordValid = await user.validatePassword(currentPassword);
    if (!isCurrentPasswordValid) {
      throw new BusinessError('当前密码错误');
    }

    // 检查新密码是否与当前密码相同
    const isSamePassword = await user.validatePassword(newPassword);
    if (isSamePassword) {
      throw new BusinessError('新密码不能与当前密码相同');
    }

    // 更新密码
    await user.update({ password: newPassword });

    // 记录操作日志
    await UserLog.create({
      user_id: user.id,
      action: 'password_change',
      details: JSON.stringify({ message: '用户修改密码' }),
      ip: req.ip,
      user_agent: req.get('User-Agent')
    });

    res.json({
      code: 200,
      message: '密码修改成功'
    });
  })
);

export default router;
